package com.haiyou.data.common.accessor.redis.redisson.bucket;

import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;

import org.redisson.api.RExecutorService;
import org.redisson.api.RLexSortedSet;
import org.redisson.api.RSortedSet;
import org.redisson.api.WorkerOptions;

import com.google.common.collect.Lists;
import com.haiyou.common.entity.Entity;
import com.haiyou.common.util.reflect.AnnotationFinder;
import com.haiyou.data.common.accessor.annotation.SizePolicy;
import com.haiyou.data.common.cache.redis.RKeys;

/**
 * 分布式对象桶+分布式有序容器，适合用在经常需要调用getAll函数，元素缓存存活时间较短的排行榜
 * 
 * @author Administrator
 *
 * @param <V>
 */
public abstract class SortedBucketAccessor<V extends Entity<String>> extends RedissonBucketAccessor<V>
		implements Comparator<V> {

	private static final String SORTED_SUFFIX = "SortedView";
	
	protected RSortedSet<V> sortedSet;
	protected int greed_length;

	@Override
	public void init() {
		super.init();

		SizePolicy sizePolicy = AnnotationFinder.findAnnotation(getClass(), SizePolicy.class);
		if (sizePolicy == null) {
			greed_length = 1000;
		} else {
			greed_length = sizePolicy.maximumSize();
		}
		greed_length = Math.max(greed_length, 1);
		greed_length = Math.min(greed_length, 100000);

		redissonClient.getExecutorService(RExecutorService.MAPREDUCE_NAME).registerWorkers(WorkerOptions.defaults());

		sortedSet = redissonClient.getSortedSet(RKeys.createRKey(RLexSortedSet.class, keyPrefix, SORTED_SUFFIX));
		sortedSet.trySetComparator(this);
	}

	@Override
	public abstract int compare(V o1, V o2);

	/**
	 * 返回此集合中元素严格小于 toElement 的部分的视图
	 * 
	 * @param toElement
	 * @return
	 */
	public List<V> headList(V toElement) {
		SortedSet<V> set = sortedSet.headSet(toElement);
		List<V> result = Lists.newArrayListWithCapacity(set.size());
		Iterator<V> iterator = set.iterator();
		while (iterator.hasNext()) {
			result.add(iterator.next());
		}
		return result;
	}

	/**
	 * 返回此集合中元素大于或等于 fromElement 的部分的视图
	 * 
	 * @param toElement
	 * @return
	 */
	public List<V> tailList(V toElement) {
		SortedSet<V> set = sortedSet.tailSet(toElement);
		List<V> result = Lists.newArrayListWithCapacity(set.size());
		Iterator<V> iterator = set.iterator();
		while (iterator.hasNext()) {
			result.add(iterator.next());
		}
		return result;
	}

	/**
	 * 返回此集合的一部分的视图，其元素范围从 fromElement,inclusive 到 toElement,exclusive。 （如果
	 * fromElement 和 toElement 相等，则返回的集合为空。）
	 * 
	 * @param fromElement
	 * @param toElement
	 * @return
	 */
	public List<V> subList(V fromElement, V toElement) {
		SortedSet<V> set = sortedSet.subSet(fromElement, toElement);
		List<V> result = Lists.newArrayListWithCapacity(set.size());
		Iterator<V> iterator = set.iterator();
		while (iterator.hasNext()) {
			result.add(iterator.next());
		}
		return result;
	}

	private void reSize() {
		while (sortedSet.size() > greed_length) {
			sortedSet.removeAsync(sortedSet.last());
		}
	}

	@Override
	public V put(String key, V value) {
		V old = get(key);
		if (old != null)
			sortedSet.removeAsync(old);// TODO 要确保value的唯一性，为了兼容value的成员内容可被修改，每次添加之前先删掉旧的
		sortedSet.addAsync(value);
		reSize();
		return super.put(key, value);
	}

	@Override
	public void putAll(Map<? extends String, ? extends V> m) {
		Map<String, V> map = getAll(m.keySet());
		if (map != null && !map.isEmpty())// TODO 要确保value的唯一性，为了兼容value的成员内容可被修改，每次添加之前先删掉旧的
			sortedSet.removeAll(map.values());
		sortedSet.addAll(m.values());
		reSize();
		super.putAll(m);
	}

	@Override
	public V remove(Object key) {
		V old = super.remove(key);
		if (old != null)
			sortedSet.removeAsync(old);
		return old;
	}

	@Override
	public void removeAll(Iterable<? extends String> keys) {
		sortedSet.removeAll(getAll(keys).values());
		super.removeAll(keys);
	}

}
